﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Player : MonoBehaviour {

    public int trailLength;
    public Color TrailColor;
    public Material TrailMaterial;
    public float timeBetweenTrailAdditions;
    public float timeTillTrailElementMoved;

	public int Id { get; private set; }
	
	protected List<TrailElement> Trail = new List<TrailElement>();
	protected List<TrailElement> FakeTrail = new List<TrailElement>();
	protected bool TrailEnabled;
	protected float TimeAtLastFakeTrailAddition = 0.0f;
	
	// Adds a new element to the trail, if possible (function is called from elsewhere, if "trailEnabled" is true.
	void AddTrailElement(bool blinked) {
		Trail.Add(new TrailElement(transform.position, blinked));
		
		if (Trail.Count > trailLength) {
		    var e = Trail[0];
		    Destroy(e.Visual);
			Trail.RemoveAt(0);
		}
	}
	
	void DrawTrail() {
	    var prev = default(TrailElement) ;
	    for (int i = 0; i < Trail.Count; i++) {
	        var t = Trail[i];
            Debug.Log(t.Blink + " " + t.Position + " " + t.Visual);
	        if (i == 0 || i == Trail.Count - 1) {
	            prev = Trail[i];
                continue;
	        }
	        if (prev.Visual == null) {
                prev.Visual = new GameObject("trail");
	            var r = prev.Visual.AddComponent<LineRenderer>();
	            r.material = TrailMaterial;
	            r.SetWidth(0.3f, 0.3f);
                r.SetColors(TrailColor, TrailColor);
	            if (!prev.Blink) {
                    r.SetVertexCount(2);
	                r.SetPosition(0, prev.Position);
	                r.SetPosition(1, Trail[i].Position);
	            } else {
	                r.SetVertexCount(0);
	            }
	            
	        }
	        prev = Trail[i];
	    }
	}

    IEnumerator TrailDrawer() {
        while (true) {
            yield return new WaitForSeconds(timeBetweenTrailAdditions);
            DrawTrail();
        }
    }

    private void StartTrailDrawer() {
        StartCoroutine(TrailDrawer());
    }

    private Control _control;
	// Use this for initialization
	void Start () {
	    _control = GetComponent<Control>();
        Invoke("toggleOn", 0);
        Invoke("StartTrailDrawer", 5);
	}

    private void toggleOn() {
        ToggleTrail(true);
    }
	
	public void ToggleTrail(bool enabled) {
		TrailEnabled = enabled;
		if (!TrailEnabled) {
			Trail.Clear();
		}
	}
	
	// Update is called once per frame
	void Update () {
        // A "fake" trail element is added to the player's list
		if ((Time.realtimeSinceStartup - TimeAtLastFakeTrailAddition) > timeBetweenTrailAdditions) {
		    var blinked = _control.BlinkTime > TimeAtLastFakeTrailAddition &&
		                  _control.BlinkTime < TimeAtLastFakeTrailAddition + timeBetweenTrailAdditions;
            TimeAtLastFakeTrailAddition = Time.realtimeSinceStartup;
            
			FakeTrail.Add(new TrailElement(transform.position, blinked));
		}
		// Runs through the list of Fake Trail
	    foreach (TrailElement element in FakeTrail) {
	        // Checks for elements that has been in the Fake Trail to the point of getting added to the Real Trail
	        if ((element.TimeAdded + timeTillTrailElementMoved) > Time.realtimeSinceStartup) {
	            // Is the trail Enabled? Woop!
	            if (TrailEnabled) {
	                AddTrailElement(element.Blink);
	            }
	        }
	    }
	    FakeTrail.RemoveAll(e => (e.TimeAdded + timeTillTrailElementMoved) > Time.realtimeSinceStartup);
	}
}